package logv

import (
	"fmt"
	"strings"
	"time"

	"github.com/rs/zerolog"
)

// 示例钩子实现

// TimestampHook 添加自定义时间戳格式的钩子
type TimestampHook struct {
	TimeFormat string
}

func NewTimestampHook(format string) *TimestampHook {
	return &TimestampHook{TimeFormat: format}
}

func (h *TimestampHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	e.Str("custom_time", time.Now().Format(h.TimeFormat))
}

// HostnameHook 添加主机名的钩子
type HostnameHook struct {
	Hostname string
}

func NewHostnameHook(hostname string) *HostnameHook {
	return &HostnameHook{Hostname: hostname}
}

func (h *HostnameHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	e.Str("hostname", h.Hostname)
}

// ErrorCountHook 统计错误数量的钩子
type ErrorCountHook struct {
	ErrorCount int
}

func NewErrorCountHook() *ErrorCountHook {
	return &ErrorCountHook{}
}

func (h *ErrorCountHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	if level >= zerolog.ErrorLevel {
		h.ErrorCount++
		e.Int("total_errors", h.ErrorCount)
	}
}

// SensitiveDataHook 敏感数据脱敏钩子
type SensitiveDataHook struct {
	SensitiveWords []string
}

func NewSensitiveDataHook(words []string) *SensitiveDataHook {
	return &SensitiveDataHook{SensitiveWords: words}
}

func (h *SensitiveDataHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	sanitizedMsg := msg
	for _, word := range h.SensitiveWords {
		if strings.Contains(sanitizedMsg, word) {
			sanitizedMsg = strings.ReplaceAll(sanitizedMsg, word, "***")
		}
	}
	if sanitizedMsg != msg {
		e.Str("original_msg_sanitized", "true")
	}
}

// AlertHook 告警钩子，当错误级别达到一定程度时发送告警
type AlertHook struct {
	AlertFunc func(level zerolog.Level, msg string)
}

func NewAlertHook(alertFunc func(level zerolog.Level, msg string)) *AlertHook {
	return &AlertHook{AlertFunc: alertFunc}
}

func (h *AlertHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	if level >= zerolog.ErrorLevel && h.AlertFunc != nil {
		go h.AlertFunc(level, msg) // 异步执行告警
	}
}

// 使用示例函数

// ExampleBasicHook 基本钩子使用示例
func ExampleBasicHook() {
	// 添加简单的函数钩子
	AddHook(HookFunc(func(e *zerolog.Event, level zerolog.Level, msg string) {
		e.Str("hook_type", "basic")
		e.Str("level_name", level.String())
	}))

	Info("这是一条测试日志")
}

// ExampleTimestampHook 时间戳钩子使用示例
func ExampleTimestampHook() {
	// 添加自定义时间戳钩子
	timestampHook := NewTimestampHook("2006-01-02 15:04:05.000")
	AddHook(timestampHook)

	Info("带自定义时间戳的日志")
}

// ExampleLevelHook 级别过滤钩子使用示例
func ExampleLevelHook() {
	// 只在错误和致命错误级别时添加额外信息
	errorHook := HookFunc(func(e *zerolog.Event, level zerolog.Level, msg string) {
		e.Str("severity", "high")
		e.Bool("needs_attention", true)
	})

	levelHook := NewLevelHook([]zerolog.Level{zerolog.ErrorLevel, zerolog.FatalLevel}, errorHook)
	AddHook(levelHook)

	Info("这是普通信息，不会触发钩子")
	Error("这是错误信息，会触发钩子")
}

// ExampleConditionalHook 条件钩子使用示例
func ExampleConditionalHook() {
	// 只在消息包含特定关键词时添加标记
	conditionalHook := NewConditionalHook(
		func(level zerolog.Level, msg string) bool {
			return strings.Contains(msg, "database") || strings.Contains(msg, "sql")
		},
		HookFunc(func(e *zerolog.Event, level zerolog.Level, msg string) {
			e.Str("category", "database")
			e.Bool("db_related", true)
		}),
	)

	AddHook(conditionalHook)

	Info("普通日志消息")
	Info("database connection established") // 会触发钩子
	Error("sql query failed")              // 会触发钩子
}

// ExampleMultipleHooks 多个钩子使用示例
func ExampleMultipleHooks() {
	// 添加多个钩子
	AddHook(NewTimestampHook("15:04:05"))
	AddHook(NewHostnameHook("web-server-01"))
	
	errorCountHook := NewErrorCountHook()
	AddHook(errorCountHook)

	// 添加告警钩子
	alertHook := NewAlertHook(func(level zerolog.Level, msg string) {
		fmt.Printf("ALERT: [%s] %s\n", level.String(), msg)
	})
	AddHook(alertHook)

	Info("应用启动")
	Warn("内存使用率较高")
	Error("数据库连接失败") // 会触发告警
}

// ExampleSensitiveDataHook 敏感数据脱敏钩子示例
func ExampleSensitiveDataHook() {
	// 添加敏感数据脱敏钩子
	sensitiveHook := NewSensitiveDataHook([]string{"password", "token", "secret"})
	AddHook(sensitiveHook)

	Info("用户登录成功")
	Info("password: 123456") // 敏感信息会被标记
}

// ExampleCommonFieldsHook 公共字段钩子示例
func ExampleCommonFieldsHook() {
	// 方式1: 使用全局公共字段函数（推荐）
	SetCommonFields(map[string]interface{}{
		"app_name":    "my-service",
		"version":     "1.2.3",
		"environment": "production",
		"region":      "us-east-1",
	})

	// 添加单个公共字段
	AddCommonField("instance_id", "i-1234567890abcdef0")

	Info("服务启动")
	Error("数据库连接失败")
	Warn("内存使用率较高")

	// 动态修改公共字段
	AddCommonField("status", "degraded")
	Error("服务降级")

	// 移除某个公共字段
	RemoveCommonField("status")
	Info("服务恢复正常")
}

// ExampleCustomCommonFieldsHook 自定义公共字段钩子示例
func ExampleCustomCommonFieldsHook() {
	// 方式2: 创建自定义的公共字段钩子
	commonHook := NewCommonFieldsHook(map[string]interface{}{
		"service":   "user-service",
		"component": "authentication",
	})

	// 动态添加字段
	commonHook.AddField("build_id", "build-20231201-001")

	AddHook(commonHook)

	Info("用户认证模块初始化")
	Error("JWT token 验证失败")

	// 运行时修改字段
	commonHook.AddField("alert_level", "high")
	Error("连续认证失败，可能存在攻击")
}

// ExampleMixedCommonFields 混合使用公共字段示例
func ExampleMixedCommonFields() {
	// 清空现有钩子
	ClearHooks()

	// 设置基础公共字段
	SetCommonFields(map[string]interface{}{
		"app":     "e-commerce",
		"version": "3.1.4",
	})

	// 添加其他钩子
	AddHook(HookFunc(func(e *zerolog.Event, level zerolog.Level, msg string) {
		e.Str("request_id", "req-"+generateID())
	}))

	// 根据不同模块添加不同的公共字段
	AddCommonField("module", "order")
	Info("订单创建成功")

	// 切换模块
	AddCommonField("module", "payment")
	Info("支付处理中")
	Error("支付网关超时")

	// 切换模块
	AddCommonField("module", "inventory")
	Warn("库存不足")
}

// generateID 生成示例ID
func generateID() string {
	return "12345678"
}